garmin_gpi: Add options 'sleep', 'speed' and 'proximity'.
authoroliskoli <oliskoli>
Sat, 22 Mar 2008 13:02:01 +0000 (13:02 +0000)
committeroliskoli <oliskoli>
Sat, 22 Mar 2008 13:02:01 +0000 (13:02 +0000)
garmin_gpi.c
xmldoc/formats/garmin_gpi.xml
xmldoc/formats/options/garmin_gpi-proximity.xml [new file with mode: 0644]
xmldoc/formats/options/garmin_gpi-sleep.xml [new file with mode: 0644]
xmldoc/formats/options/garmin_gpi-speed.xml [new file with mode: 0644]

index 027d8e3417dbc406ab94adb043c6f6fb9c61d009..e2b9ec07ff8efcacb590047db8a8158f037c6c3a 100644 (file)
@@ -35,6 +35,7 @@
        * 2007/10/20: add option unique
        * 2007/12/02: support speed and proximity distance (+ alerts)
        * 2008/01/14: fix structure error after adding speed/proximity
+       * 2008/03/22: add options "speed" and "proximity" (default values) and "sleep"
 
        ToDo:
        
@@ -68,7 +69,9 @@
 #define GPI_ADDR_ADDR          16
 
 static char *opt_cat, *opt_pos, *opt_notes, *opt_hide_bitmap, *opt_descr, *opt_bitmap;
-static char *opt_unique, *opt_alerts, *opt_units;
+static char *opt_unique, *opt_alerts, *opt_units, *opt_speed, *opt_proximity, *opt_sleep;
+static double defspeed, defproximity;
+static int alerts;
 
 static arglist_t garmin_gpi_args[] = {
        {"alerts", &opt_alerts, "Enable alerts on speed or proximity distance", 
@@ -85,6 +88,12 @@ static arglist_t garmin_gpi_args[] = {
                NULL, ARGTYPE_BOOL, ARG_NOMINMAX},
        {"position", &opt_pos, "Write position to address field", 
                NULL, ARGTYPE_BOOL, ARG_NOMINMAX},
+       {"proximity", &opt_proximity, "Default proximity", 
+               NULL, ARGTYPE_FLOAT, ARG_NOMINMAX},
+       {"sleep", &opt_sleep, "After output job done sleep n second(s)", 
+               NULL, ARGTYPE_INT, "1", NULL},
+       {"speed", &opt_speed, "Default speed", 
+               NULL, ARGTYPE_FLOAT, ARG_NOMINMAX},
        {"unique", &opt_unique, "Create unique waypoint names (default = yes)", 
                "Y", ARGTYPE_BOOL, ARG_NOMINMAX},
        {"units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", 
@@ -171,7 +180,8 @@ static gbint32 codepage;    /* code-page, i.e. 1252 */
 static reader_data_t *rdata;
 static writer_data_t *wdata;
 static short_handle short_h;
-char units;
+static char units;
+static time_t gpi_timestamp = 0;
 
 #ifdef GPI_DBG
 # define PP warning("@%1$6x (%1$8d): ", gbftell(fin))
@@ -727,19 +737,25 @@ wdata_compute_size(writer_data_t *data)
                dt = xcalloc(1, sizeof(*dt));
                wpt->extra_data = dt;
                
-               if (opt_alerts) {
+               if (alerts) {
                        char *pos;
                        
                        if ((pos = strchr(wpt->shortname, '@'))) {
-                               float f = atoi(pos + 1);
-                               if (units == 's') f = MPH_TO_MPS(f);
-                               else f = KPH_TO_MPS(f);
-                               if (f > 0) WAYPT_SET(wpt, speed, f);
+                               double speed, scale;
+                               if (units == 's') scale = MPH_TO_MPS(1);
+                               else scale = KPH_TO_MPS(1);
+                               parse_speed(pos + 1, &speed, scale, MYNAME);
+                               if (speed > 0) WAYPT_SET(wpt, speed, speed);
 #if 0                          
                                if (pos > wpt->shortname) wpt->shortname[pos - wpt->shortname] = '\0';
 #endif
                        }
+                       else if ((opt_speed) && (! WAYPT_HAS(wpt, speed)))
+                               WAYPT_SET(wpt, speed, defspeed);
                        
+                       if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity)))
+                               WAYPT_SET(wpt, proximity, defproximity);
+
                        if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || 
                            (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) {
                                data->alert = 1;
@@ -957,10 +973,11 @@ write_category(const char *category, const char *image, const int image_sz)
 static void
 write_header(void)
 {
-       time_t time = gpsbabel_time;    /* !!! ZERO during leaktest !!! */
+       time_t time = gpi_timestamp;
 
        if (time != 0) {
-               struct tm tm = *gmtime(&time);
+               struct tm tm;
+               tm = *gmtime(&time);
                tm.tm_year -= 20;
                time = mkgmtime(&tm);
                time += SECONDS_PER_DAY;
@@ -1188,6 +1205,16 @@ garmin_gpi_wr_init(const char *fname)
        cet_cs_vec_t *vec;
        int i;
        
+       if (gpi_timestamp != 0) {                       /* not the first gpi output session */ 
+               time_t t = time(NULL);
+               if (t <= gpi_timestamp)
+                       gpi_timestamp++;                /* don't create files with same timestamp */
+               else
+                       gpi_timestamp = t;
+       }
+       else
+               gpi_timestamp = gpsbabel_time;          /* always ZERO during 'testo' */
+       
        fout = gbfopen_le(fname, "wb", MYNAME);
        
        short_h = mkshort_new_handle();
@@ -1220,6 +1247,23 @@ garmin_gpi_wr_init(const char *fname)
        if ((units != 'm') && (units != 's'))
                fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]);
 
+       alerts = (opt_alerts) ? 1 : 0;
+
+       if (opt_speed) {
+               double scale;
+               alerts = 1;                                     /* Force alerts to be enabled */
+               if (units == 's') scale = MPH_TO_MPS(1);        /* We need speed in meters per second */
+               else scale = KPH_TO_MPS(1);
+               parse_speed(opt_speed, &defspeed, scale, MYNAME);
+       }
+
+       if (opt_proximity) {
+               double scale;
+               alerts = 1;                                     /* Force alerts to be enabled */
+               if (units == 's') scale = MILES_TO_METERS(1);   /* We need proximity in meters */
+               else scale = 1000.0;                            /* one kilometer in meters */
+               parse_distance(opt_proximity, &defproximity, scale, MYNAME);
+       }
        wdata = wdata_alloc();
 }
 
@@ -1240,6 +1284,15 @@ garmin_gpi_wr_deinit(void)
        wdata_free(wdata);
        mkshort_del_handle(&short_h);
        gbfclose(fout);
+
+       if ((opt_sleep) && (gpi_timestamp != 0)) {      /* don't sleep during 'testo' */
+               int sleep = atoi(opt_sleep);
+               if (sleep < 1) sleep = 1;
+               gpi_timestamp += sleep;
+               while (gpi_timestamp > time(NULL)) {
+                       gb_sleep(100);
+               }
+       }
 }
 
 
index 14d5f379d540ad25c053e1e88084cc6f4a895146..43a1657382fc8a44d44e6eba215d0da526584a44 100644 (file)
    a GPI file, please provide that file (mailto:gpsbabel-misc@lists.sourceforge.net).
 </para>
 <para>
-   At this time we don't support special features as "Tour-Guide", alerts or links
+   At this time we don't support special features as "Tour-Guide" or links
    to sounds and pictures.
 </para>
+<important>
+<para>
+   Creation timestamp issue: See option <link linkend="fmt_garmin_gpi_o_sleep">sleep</link> !!!
+</para>
 <para>
        This module does not support direct transfer of .GPI files to
        receivers in Garmin protocol mode.  For units like Nuvi, Zumo, or 
@@ -22,6 +26,7 @@
        the memory chip in an external reader and transfer the file 
        directly.
 </para>
+</important>
 <example id="all_garmin_gpi_options">
   <title>Command showing garmin_gpi output example</title>
   <para>
diff --git a/xmldoc/formats/options/garmin_gpi-proximity.xml b/xmldoc/formats/options/garmin_gpi-proximity.xml
new file mode 100644 (file)
index 0000000..1912172
--- /dev/null
@@ -0,0 +1,61 @@
+<para>
+  When no proximity data is available GPSBabel uses this as default proximity value.
+  The parameter has to be in meters, or, when units=s specified, in miles.
+  <link linkend="fmt_garmin_gpi_o_alerts">alerts</link> are automatically enabled.
+</para>
+<para>
+  <userinput>
+    gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,proximity=0.5 -F "SpeedCameras.gpi"
+  </userinput>
+</para>
+<para>
+  Its also possible to append a specific distance unit to the parameter.
+</para>
+<para>
+  <userinput>
+    gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,proximity=500m -F "SpeedCameras.gpi"
+  </userinput>
+</para>
+<para>
+  <table id="distance_units">
+  <title>Supported distance units</title>
+  <tgroup cols="2">
+  <thead>
+  <row>
+    <entry>Unit</entry> 
+    <entry>Description</entry> 
+  </row>
+  </thead>
+  <tbody>
+  <row>
+    <entry>fa</entry>
+    <entry>Fathoms</entry>
+  </row>
+  <row>
+    <entry>feet</entry>
+    <entry>Feet</entry>
+  </row>
+  <row>
+    <entry>ft</entry>
+    <entry>Feet</entry>
+  </row>
+  <row>
+    <entry>km</entry>
+    <entry>Kilometers</entry>
+  </row>
+  <row>
+    <entry>m</entry>
+    <entry>Meters</entry>
+  </row>
+  <row>
+    <entry>mi</entry>
+    <entry>Miles</entry>
+  </row>
+  <row>
+    <entry>nm</entry>
+    <entry>Nautical miles</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+</para>
diff --git a/xmldoc/formats/options/garmin_gpi-sleep.xml b/xmldoc/formats/options/garmin_gpi-sleep.xml
new file mode 100644 (file)
index 0000000..a852677
--- /dev/null
@@ -0,0 +1,16 @@
+<para>
+  Garmin units seems to use the creation timestamp of GPI files for internal jobs. 
+  In other words,  if you load GPI files with same creation timestamp on your device, 
+  strange things will happen (missing or repeated POIs). With sleep GPSbabel waits a given
+  number of seconds after the GPI file was written.
+</para>
+<para>
+  In normal case, when using GPSBabel from commandline or from the GUI, the chance to get files
+  with same timestamp is in the nearly ZERO. In scripts or batch files this looks quiet other.
+  Here we suggess the use of the sleep option. Values can be 1 (second) or more.
+</para>
+<para>
+  <userinput>
+    gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,sleep=1 -F "SpeedCameras.gpi"
+  </userinput>
+</para>
diff --git a/xmldoc/formats/options/garmin_gpi-speed.xml b/xmldoc/formats/options/garmin_gpi-speed.xml
new file mode 100644 (file)
index 0000000..4c23a68
--- /dev/null
@@ -0,0 +1,66 @@
+<para>
+  When no speed data is available GPSBabel uses this as default speed value.
+  The parameter has to be in kilometers per hour, or, when units=s specified,
+  in miles per hour. <link linkend="fmt_garmin_gpi_o_alerts">alerts</link> are
+  automatically enabled.
+</para>
+<para>
+  <userinput>
+    gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,units=s,speed=30 -F "SpeedCameras.gpi"
+  </userinput>
+</para>
+<para>
+  Its also possible to append a specific speed unit to the parameter.
+</para>
+<para>
+  <userinput>
+    gpsbabel -i gpx -f "SpeedCameras.gpx" -o garmin_gpi,speed=30mph -F "SpeedCameras.gpi"
+  </userinput>
+</para>
+<para>
+  <table id="speed_units">
+  <title>Supported speed units</title>
+  <tgroup cols="2">
+  <thead>
+  <row>
+    <entry>Unit</entry> 
+    <entry>Description</entry> 
+  </row>
+  </thead>
+  <tbody>
+  <row>
+    <entry>km/h</entry>
+    <entry>Kilometers per hour</entry>
+  </row>
+  <row>
+    <entry>kmh</entry>
+    <entry>Kilometers per hour</entry>
+  </row>
+  <row>
+    <entry>kph</entry>
+    <entry>Kilometers per hour</entry>
+  </row>
+  <row>
+    <entry>kt</entry>
+    <entry>Knots</entry>
+  </row>
+  <row>
+    <entry>knot</entry>
+    <entry>Knots</entry>
+  </row>
+  <row>
+    <entry>m/s</entry>
+    <entry>Meters per second</entry>
+  </row>
+  <row>
+    <entry>mps</entry>
+    <entry>Meters per second</entry>
+  </row>
+  <row>
+    <entry>mi/h</entry>
+    <entry>Miles per hour</entry>
+  </row>
+</tbody>
+</tgroup>
+</table>
+</para>